package com.ejiaoyi.common.util;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;

/**
 * Redisson 分布式锁工具类
 *
 * @author unknownChivalrous
 * @since 2020/3/25
 */
public class RedissonUtil {

    private static RedissonClient redissonClient;

    public void setRedissonClient(RedissonClient redissonClient) {
        RedissonUtil.redissonClient = redissonClient;
    }

    /**
     * 加锁
     *
     * @param key 锁的key值
     * @return RLock对象
     */
    public static RLock lock(String key) {
        RLock rLock = redissonClient.getLock(key);
        rLock.lock();
        return rLock;
    }

    /**
     * 加锁
     *
     * @param key     锁的key值
     * @param timeout 超时时间 seconds
     * @return RLock对象
     */
    public static RLock lock(String key, int timeout) {
        return RedissonUtil.lock(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 加锁
     *
     * @param key      锁的key值
     * @param timeout  超时时间
     * @param timeUnit 超时单位
     * @return RLock对象
     */
    public static RLock lock(String key, int timeout, TimeUnit timeUnit) {
        RLock rLock = redissonClient.getLock(key);
        rLock.lock(timeout, timeUnit);
        return rLock;
    }

    /**
     * 释放锁
     *
     * @param key 锁的key值
     */
    public static void unlock(String key) {
        RLock rLock = redissonClient.getLock(key);
        rLock.unlock();
    }

    /**
     * 尝试获取锁
     *
     * @param key       锁的key值
     * @param waitTime  最大等待时间 seconds
     * @param leaseTime 上锁后的自动释放时间 seconds
     * @return 是否成功获取到锁
     */
    public static boolean tryLock(String key, int waitTime, int leaseTime) {
        return RedissonUtil.tryLock(key, TimeUnit.SECONDS, waitTime, leaseTime);
    }

    /**
     * 尝试获取锁
     *
     * @param key       锁的key值
     * @param timeUnit  时间单位
     * @param waitTime  最大等待时间
     * @param leaseTime 上锁后的自动释放时间
     * @return 是否成功获取到锁
     */
    public static boolean tryLock(String key, TimeUnit timeUnit, int waitTime, int leaseTime) {
        RLock rLock = redissonClient.getLock(key);
        try {
            return rLock.tryLock(waitTime, leaseTime, timeUnit);
        } catch (InterruptedException e) {
            return false;
        }
    }

    /**
     * 释放锁
     *
     * @param rLock RLock对象
     */
    public static void unlock(RLock rLock) {
        rLock.unlock();
    }
}